//////////////////////////////////////////////////////////////////////////
///	\file:	TPPlayer.cpp
///	Copyright (Home) 2010 - All Rights Reserved
///	Author:	Robert.Ma
///	Date:	[2010/01/31]
///	Description:
///		
//////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "TPPlayer.h"
#include "TPFile.h"
#include "maplay.h"
#include "TPTrack.h"
#include "TPDefine.h"

#include "TPAuthCenter.h"

CTPPlayer::CTPPlayer(void)
		: m_hMPlayer(NULL),
		m_iCurIndex(0)
{
	m_hMPlayer = ::MAP_Initialize();
}

CTPPlayer::~CTPPlayer(void)
{
	::MAP_Uninitialize(m_hMPlayer);
}

CTPPlayer* CTPPlayer::Instance()
{
	static Smart_ptr::SmartPtr<CTPPlayer> spPlayer;

	if ( NULL == spPlayer )
	{
		spPlayer = new CTPPlayer();
	}

	return spPlayer;
}

void CTPPlayer::RemoveAllFiles()
{
	CTPPlayer* pInstance = Instance();

	pInstance->m_fileBuf.RemoveAll();
}

BOOL CTPPlayer::LoadTPFile(LPCTSTR lpszFile)
{
	BOOL bResult = FALSE;

	CTPFilePtr pFile = new CTPFile;

	if ( pFile->Load(lpszFile) )
	{
		CTPPlayer* pInstance = Instance();

		bResult = pInstance->m_fileBuf.Add(pFile);
	}

	return bResult;
}

BOOL CTPPlayer::RemoveFile(int iIndex)
{
	CTPPlayer* pInstance = Instance();

	BOOL bResult = pInstance->m_fileBuf.RemoveAt(iIndex);

	return bResult;
}

int CTPPlayer::GetTPFileCount()
{
	CTPPlayer* pInstance = Instance();

	return pInstance->m_fileBuf.GetSize();
}

const CTPFile* CTPPlayer::GetTPFile(int iIndex/* = -1*/)
{
	CTPPlayer* pInstance = Instance();

	const CTPFile* pRet = NULL;

	if ( -1 == iIndex )
	{
		iIndex = pInstance->m_iCurIndex;
	}

	if ( 0 <= iIndex && iIndex < pInstance->m_fileBuf.GetSize() )
	{
		pRet = pInstance->m_fileBuf[iIndex];
	}

	return pRet;
}

BOOL CTPPlayer::Pause()
{
	BOOL bResult = FALSE;
	CTPPlayer* pInstance = Instance();

	if ( MAP_STATUS_PLAY == ::MAP_GetStatus(pInstance->m_hMPlayer) )
	{
		::MAP_Pause(pInstance->m_hMPlayer);

		bResult = TRUE;
	}

	return bResult;
}

BOOL CTPPlayer::Play()
{
	BOOL bResult = FALSE;
	CTPPlayer* pInstance = Instance();

	const CTPFile* pFile = GetTPFile(pInstance->m_iCurIndex);

	if ( NULL != pFile )
	{
		if ( CTPAuthCenter::GetAuthorize(pFile->GetTitle(), pFile->GetDestNum()) )
		{
			bResult = ::MAP_Play(pInstance->m_hMPlayer);

			if ( !bResult )
			{
				::MAP_Open(pInstance->m_hMPlayer, pFile->GetFile());

				bResult = ::MAP_Play(pInstance->m_hMPlayer);
			}
		}
	}

	return bResult;
}

void CTPPlayer::Stop()
{
	CTPPlayer* pInstance = Instance();

	::MAP_Stop(pInstance->m_hMPlayer);
}

BOOL CTPPlayer::Seek(int iTrack /* = 0 */, int iIndex /* = -1 */)
{
	CTPPlayer* pInstance = Instance();
	BOOL bResult = FALSE;

	BOOL bOpen = false;

	if ( -1 == iIndex )
	{
		iIndex = pInstance->m_iCurIndex;
	}
	else
	{
		bOpen = (pInstance->m_iCurIndex == iIndex);
	}

	const CTPFile* pFile = GetTPFile(iIndex);

	if ( NULL != pFile )
	{
		const TRACK* pTrack = pFile->GetTrackByIndex(iTrack);

		if ( NULL != pTrack )
		{
			if ( !bOpen && CTPAuthCenter::GetAuthorize(pFile->GetTitle(), pFile->GetDestNum()) )
			{
				bOpen = ::MAP_Open(pInstance->m_hMPlayer, pFile->GetFile());
			}

			if ( bOpen && ::MAP_Seek(pInstance->m_hMPlayer, pTrack->index.wIndex * uiSeconds) )
			{
				bResult = ::MAP_Play(pInstance->m_hMPlayer);
			}
		}
	}

	return bResult;
}

int CTPPlayer::GetTrackCount(int iIndex /* = -1 */)
{
	int iCount = -1;

	if ( -1 == iIndex )
	{
		CTPPlayer* pInstance = Instance();

		iIndex = pInstance->m_iCurIndex;
	}

	const CTPFile* pFile = GetTPFile(iIndex);

	if ( NULL != pFile )
	{
		iCount = pFile->GetTrackCount();
	}

	return iCount;
}

const TRACK* CTPPlayer::GetTrackByIndex(int iTrack /* = 0 */, int iIndex /* = -1 */)
{
	const TRACK* pTrack = NULL;

	if ( -1 == iIndex )
	{
		CTPPlayer* pInstance = Instance();

		iIndex = pInstance->m_iCurIndex;
	}

	const CTPFile* pFile = GetTPFile(iIndex);

	if ( NULL != pFile )
	{
		pTrack = pFile->GetTrackByIndex(iTrack);
	}

	return pTrack;
}

BOOL CTPPlayer::GetCurrent(int& iTrack, int& iIndex)
{
	BOOL bResult = FALSE;
	CTPPlayer* pInstance = Instance();

	if ( 0 <= pInstance->m_iCurIndex && pInstance->m_iCurIndex < pInstance->m_fileBuf.GetSize() )
	{
		iIndex = pInstance->m_iCurIndex;

		CTPFile*		pFile	= pInstance->m_fileBuf[iIndex];
		DWORD			dwTime	= MAP_GetCurrent(pInstance->m_hMPlayer) / uiSeconds;
		const TRACK*	pTrack	= NULL;

		bResult = pFile->GetTrack(dwTime, iTrack, &pTrack);
	}

	return bResult;
}

BOOL CTPPlayer::Next()
{
	BOOL bResult = FALSE;

	CTPPlayer* pInstance = Instance();

	if ( 0 <= pInstance->m_iCurIndex && pInstance->m_iCurIndex < pInstance->m_fileBuf.GetSize() )
	{
		CTPFile*		pFile	= pInstance->m_fileBuf[pInstance->m_iCurIndex];
		DWORD			dwTime	= MAP_GetCurrent(pInstance->m_hMPlayer) / uiSeconds;
		const TRACK*	pTrack	= NULL;
		int				iTrack	= 0;

		if ( pFile->GetTrack(dwTime, iTrack, &pTrack) )
		{
			++iTrack;

			bResult = Seek(iTrack);
		}
	}

	return bResult;
}

BOOL CTPPlayer::Prev()
{
	BOOL bResult = FALSE;

	CTPPlayer* pInstance = Instance();

	if ( 0 <= pInstance->m_iCurIndex && pInstance->m_iCurIndex < pInstance->m_fileBuf.GetSize() )
	{
		CTPFile*		pFile	= pInstance->m_fileBuf[pInstance->m_iCurIndex];
		DWORD			dwTime	= MAP_GetCurrent(pInstance->m_hMPlayer) / uiSeconds;
		const TRACK*	pTrack	= NULL;
		int				iTrack	= 0;

		if ( pFile->GetTrack(dwTime, iTrack, &pTrack) )
		{
			--iTrack;

			if ( 0 <= iTrack )
			{
				bResult = Seek(iTrack);
			}
		}
	}

	return bResult;
}

BOOL CTPPlayer::GetTrack(DWORD dwTime, int& iTrack, const TRACK** ppTrack, int iIndex /* = -1 */)
{
	BOOL bResult = FALSE;

	if ( -1 == iIndex )
	{
		CTPPlayer* pInstance = Instance();

		iIndex = pInstance->m_iCurIndex;
	}

	const CTPFile* pFile = GetTPFile(iIndex);

	if ( NULL != pFile )
	{
		bResult = pFile->GetTrack(dwTime, iTrack, ppTrack);
	}

	return bResult;
}

BOOL CTPPlayer::IsPlayStatus()
{
	CTPPlayer* pInstance = Instance();

	return MAP_STATUS_STOP != ::MAP_GetStatus(pInstance->m_hMPlayer);
}

int CTPPlayer::GetPlayTime()
{
	CTPPlayer* pInstance = Instance();

	return ::MAP_GetCurrent(pInstance->m_hMPlayer);
}

DWORD CTPPlayer::GetVolume()
{
	CTPPlayer* pInstance = Instance();

	return ::MAP_GetVolume(pInstance->m_hMPlayer, TRUE);
}

void CTPPlayer::SetVolume(DWORD dwVolume)
{
	CTPPlayer* pInstance = Instance();

	return ::MAP_SetVolume(pInstance->m_hMPlayer, dwVolume, TRUE);
}
